﻿using Microsoft.TeamFoundation.Build.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace BuildExplorer
{
    public static class IBuildInformationNodeExtentions
    {
        public static String GetNodeText(this IBuildInformationNode node)
        {
            String text = String.Empty;

            string name;
            if (node.Fields.TryGetValue("DisplayText", out name))
            {
                text = name;
            }
            else
            {
                text = node.Type;
            }

            if (node.Type == "BuildMessage" || node.Type == "BuildError" || node.Type == "BuildWarning" || node.Type == "DeploymentInformation")
            {
                string message;
                if (node.Fields.TryGetValue("Message", out message))
                {
                    text += ": " + message;
                }
            }
            else if (node.Type == "BuildProject")
            {
                string localPath;
                if (node.Fields.TryGetValue("LocalPath", out localPath))
                {
                    text += ": " + Path.GetFileName(localPath);
                }
            }
            else if (node.Type == "AssociatedChangeset")
            {
                text += ": " + node.Fields["ChangesetId"]
                    + " - " + node.Fields["CheckedInBy"].Split('\\').Last()
                    + ", " + node.Fields["Comment"];
            }
            else if (node.Type == "AssociatedWorkItem")
            {
                text += ": " + node.Fields["WorkItemId"]
                    + " - " + node.Fields["AssignedTo"].Split('\\').Last()
                    + ", " + node.Fields["Title"];
            }

            return text;
        }

        public static TimeSpan? GetDuration(this IBuildInformationNode node)
        {
            string start;
            string stop;
            DateTime startValue;
            DateTime stopValue;
            if (node.Fields.TryGetValue("StartTime", out start) &&
                node.Fields.TryGetValue("FinishTime", out stop) &&
                DateTime.TryParse(start, out startValue) &&
                DateTime.TryParse(stop, out stopValue))
            {
                var duration = stopValue - startValue;
                if (duration >= TimeSpan.Zero)
                {
                    return TimeSpan.FromSeconds((int)duration.TotalSeconds);
                }
            }

            return null;
        }

        public static IBuildInformationNode ActivityPropertiesNode(this IBuildInformationNode node)
        {
            IEnumerable<IBuildInformationNode> propNodes = node.Children.Nodes.Where(n => n.Type == "ActivityProperties");
            
            // A node with child ActivityProperties node has 2 children: one with only input, and one with input+output. So, take only the latter one.
            return propNodes.LastOrDefault();
        }

        public static IEnumerable<IBuildInformationNode> BuildMessages(this IBuildInformationNode node)
        {
            return node.Children.Nodes.Where(n => (n.Type == "BuildMessage" || n.Type == "BuildWarning" || n.Type == "BuildError"));
        }

        public static bool IsAgentScope(this IBuildInformationNode node)
        {
            return (node.Type == "AgentScopeActivityTracking");
        }

        public static IBuildInformationNode GetContainingAgentScope(this IBuildInformationNode node)
        {
            if (node.IsAgentScope())
            {
                return node;
            }

            if (node.Parent == null)
            {
                return null;
            }

            return node.Parent.GetContainingAgentScope();
        }

        public static string GetAgentScopeDescription(this IBuildInformationNode node)
        {
            if (node.IsAgentScope())
            {
                return string.Format("AgentScope '{0}': {1}, {2}, {3}",
                    node.Fields["DisplayText"],
                    node.Fields["ReservedAgentName"],
                    Util.FormatValue(node.Fields["StartTime"]),
                    node.GetDuration());
            }

            return null;
        }
    }
}
